/**
 * Created by Jack Xue on 20101024
 */
package org.code.jack.jweberp.dao;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import javax.persistence.Query;

import org.springframework.orm.jpa.JpaCallback;
import org.springframework.orm.jpa.support.JpaDaoSupport;

@SuppressWarnings(value = "unchecked")
public class GenericDaoBean<T> extends JpaDaoSupport implements IGenericDao<T>{

	public Class<T> clz;
	
	public GenericDaoBean(Class<T> clz) {
		this.clz = clz;
	}

	@Override
	public T getEntityByField(final String propertyName, final Object value, final String expression) {
		if("".equals(propertyName ) || propertyName == null || value == null){
			throw new IllegalArgumentException("getEntityByField() -> invalid argument exception");
		}
		
		final String exp = ("".equals(expression) || expression == null || "=".equals(expression) ? "=":"like");
		List<T> list = (List<T>) getJpaTemplate().execute(new JpaCallback() {
			
			@Override
			public Object doInJpa(EntityManager em) throws PersistenceException {
				StringBuffer sb = new StringBuffer("select obj from ");
				sb.append(clz.getName()).append(" obj where obj.").append(propertyName);
				sb.append(" ").append(exp).append(" :value");
				Query query = em.createQuery(sb.toString()).setParameter("value", value);
				return query.getResultList();
			}
		});
		// 对返回结果集进行处理
		if (list != null && list.size() > 1) {
			throw new IllegalArgumentException("getEntityByField() ->  result record is more than one exception.");
		} else if (list != null && list.size() == 1) {
			return list.get(0);
		} else {
			logger.debug("getEntityByField() ->  no record is found.");
			return null;
		}
	}

	@Override
	public void persistEntity(T obj) {
		this.getJpaTemplate().persist(obj);
	}

	@Override
	public T getEntity(Serializable id) {
		return this.getJpaTemplate().find(clz, id);
	}

	@Override
	public boolean mergeEntity(T obj) {
		try {
			this.getJpaTemplate().merge(obj);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	@Override
	public boolean removeEntity(Serializable id) {
		if(id != null){
			T obj = getEntity(id);
			if(obj != null){
				this.getJpaTemplate().remove(obj);
				return true;
			}else
				return false;
		}else
			return false;
	}

	@Override
	public List<T> findBySql(String sql, Object[] params, int begin, int max) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<T> findByJPQL() {
		List<T> list = (List<T>) getJpaTemplate().execute(new JpaCallback() {

			@Override
			public Object doInJpa(EntityManager em) throws PersistenceException {
				StringBuffer sb = new StringBuffer("select obj from ");
				sb.append(clz.getName()).append(" obj where 1 = 1");
				Query query = em.createQuery(sb.toString());
				return query.getResultList();
			}
		});
		// 返回结果集
		return (list != null && list.size() >= 1)? list:new ArrayList<T>();
	}

}
